package org.lora.util;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import org.lora.core.annotation.Action;
import org.lora.core.annotation.Service;

/**
 * <p>
 * 类名:ReflectUtil
 * </p>
 * 描述:<br>
 * 创建时间:2016年11月16日 下午10:21:13<br>
 * 
 * @author Bladnir@outlook.com<br>
 *         修改历史:<br>
 *         2016年11月16日 Bladnir 创建<br>
 */
public class ReflectUtil {

	/**
	 * 构造方法
	 */
	private ReflectUtil() {
		// do nothing
	}

	/**
	 * 迭代获取所有父类的成员变量数组<br>
	 * 因为实现类可能有很复杂的继承关系<br>
	 * 
	 * @param fieldList
	 * @param clz
	 * @return
	 * @throws Exception
	 */
	public static List<Field> getAllField(List<Field> fieldList, Class<?> clz) {

		Service serviceAnnotaion = clz.getAnnotation(Service.class);
		Action actionAnnotaion = clz.getAnnotation(Action.class);
		if (serviceAnnotaion != null || actionAnnotaion != null) {

			for (Field field : clz.getDeclaredFields()) {
				fieldList.add(field);
			}

			Class<?> superClass = clz.getSuperclass();
			getAllField(fieldList, superClass);
		}
		return fieldList;

	}

	/**
	 * 反射创建实体
	 * 
	 * @param clz
	 * @param map
	 * @return
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static <T> T reflectSimpleBean(Class<T> clz, Map<String, Object> map) throws NoSuchFieldException, IllegalAccessException,
			InstantiationException {

		T object = clz.newInstance();

		for (Field field : clz.getDeclaredFields()) {
			field.setAccessible(true);
			String name = field.getName();
			String value = StringUtil.getStringFromMap(name, map);

			if (StringUtil.isNotNull(value)) {

				Object resultValue = null;

				Class<?> fieldType = field.getType();

				if (Integer.TYPE.isAssignableFrom(fieldType)) {
					resultValue = Integer.valueOf(value);
				} else if (Boolean.TYPE.isAssignableFrom(fieldType)) {
					resultValue = Boolean.valueOf(value);
				} else if (String.class.isAssignableFrom(fieldType)) {
					resultValue = value.toString();
				} else if (Long.TYPE.isAssignableFrom(fieldType)) {
					resultValue = Long.valueOf(value);
				} else if (Short.TYPE.isAssignableFrom(fieldType)) {
					resultValue = Short.valueOf(value);
				} else if (Float.TYPE.isAssignableFrom(fieldType)) {
					resultValue = Float.valueOf(value);
				} else if (Double.TYPE.isAssignableFrom(fieldType)) {
					resultValue = Double.valueOf(value);
				}

				field.set(object, resultValue);

			}
		}

		return object;
	}

}
